home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / programm.ing / egem_200.lzh / EGEM.2_0 / SOURCE / TOOL.C < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-07  |  23.2 KB  |  1,161 lines

  1.  
  2. #include <time.h>
  3. #include "proto.h"
  4.  
  5. static int clipping_area[4];
  6. static int handler_events;
  7. static int (*event_init)(XEVENT *,int),(*event_handler)(XEVENT *);
  8.  
  9. char _upper(char ch)
  10. {
  11.     if (ch>='a')
  12.     {
  13.         if(ch>'z')
  14.         {
  15.             if (ch=='ä')
  16.                 return('Ä');
  17.             else if (ch=='ö')
  18.                 return('Ö');
  19.             else if (ch=='ü')
  20.                 return('Ü');
  21.         }
  22.         else
  23.             return(ch-32);
  24.     }
  25.  
  26.     return(ch);
  27. }
  28.  
  29. char _lower(char ch)
  30. {
  31.     if (ch>='A')
  32.     {
  33.         if(ch>'Z')
  34.         {
  35.             if (ch=='Ä')
  36.                 return('ä');
  37.             else if (ch=='Ö')
  38.                 return('ö');
  39.             else if (ch=='Ü')
  40.                 return('ü');
  41.         }
  42.         else
  43.             return(ch+32);
  44.     }
  45.  
  46.     return(ch);
  47. }
  48.  
  49. static int _mode,_lwidth,_lcolor,_fcolor,_finter,_fstyle,_tfont,_theight,_tcolor;
  50.  
  51. void vs_attr(void)
  52. {
  53.     _mode = _lwidth = _lcolor = _fcolor = _finter = _fstyle = _tfont = _theight = _tcolor = -1;
  54. }
  55.  
  56. void _vdi_attr(int mode,int wid,int col)
  57. {
  58.     v_set_mode(mode);
  59.     v_set_line(col,wid);
  60. }
  61.  
  62. void v_set_text(int font,int height,int color,int *out)
  63. {
  64.     if (font!=_tfont)
  65.         vst_font(x_handle,_tfont=font);
  66.  
  67.     if (out!=NULL || height!=_theight)
  68.     {
  69.         int dummy[4];
  70.  
  71.         if (out==NULL)
  72.             out = dummy;
  73.  
  74.         if (height>0)
  75.             vst_height(x_handle,height,&out[0],&out[1],&out[2],&out[3]);
  76.         else
  77.             vst_point(x_handle,-height,&out[0],&out[1],&out[2],&out[3]);
  78.         _theight = height;
  79.     }
  80.  
  81.     if (color!=_tcolor)
  82.         vst_color(x_handle,_tcolor = color);
  83. }
  84.  
  85. void v_set_mode(int mode)
  86. {
  87.     if (mode>=0 && mode!=_mode)
  88.         vswr_mode(x_handle,_mode=mode);
  89. }
  90.  
  91. void v_set_line(int color,int width)
  92. {
  93.     if (width>=0 && width!=_lwidth)
  94.         vsl_width(x_handle,_lwidth=width);
  95.  
  96.     if (color>=0 && color!=_lcolor)
  97.         vsl_color(x_handle,_lcolor=color);
  98. }
  99.  
  100. void v_set_fill(int color,int inter,int style)
  101. {
  102.     if (color>=0 && color!=_fcolor)
  103.         vsf_color(x_handle,_fcolor=color);
  104.  
  105.     if (inter>=0 && inter!=_finter)
  106.         vsf_interior(x_handle,_finter=inter);
  107.  
  108.     if (style>=0 && style!=_fstyle)
  109.         vsf_style(x_handle,_fstyle=style);
  110. }
  111.  
  112. void vsf_aespattern(int handle, int obx, int oby, int patternindex)
  113. {
  114.     static long aespatterns[] = {
  115.         0x00000000L, 0x00440011L, 0x00550055L, 0x88552288L,
  116.         0x55AA55AAL, 0xAADDAA77L, 0x55FF55FFL, 0xFFFFFFFFL };
  117.  
  118.     unsigned long pat;
  119.     reg int i,j,pattern[16];
  120.     reg char *patptr, *p;
  121.  
  122.     pat = aespatterns[patternindex];
  123.  
  124.     obx &= 3;
  125.     pat >>= obx;
  126.     pat &= 0x0F0F0F0FL;
  127.     pat |= (pat<<4);
  128.  
  129.     oby &= 3;
  130.     pat = (pat<<((4-oby)<<3))|(pat>>(oby<<3));
  131.  
  132.     patptr = (char *) pattern;
  133.     for (i=4;--i>=0;)
  134.     {
  135.         p = (char *) &pat;
  136.         for (j=4;--j>=0;)
  137.         {
  138.             *patptr++ = *p;
  139.             *patptr++ = *p++;
  140.         }
  141.     }
  142.  
  143.     vsf_interior(handle, 4);
  144.     vsf_udpat(handle, pattern, 1);
  145. }
  146.  
  147. void v_aespattern(int ob_x, int ob_y, int pattern)
  148. {
  149.     vsf_aespattern(x_handle, ob_x, ob_y, pattern);
  150.     _finter = 4;
  151. }
  152.  
  153. void _bitblt(OBJECT *tree,MFDB *form,boolean flag)
  154. {
  155.     reg int pxy[8],*ptr=pxy;
  156.     reg int x = tree->ob_x - 3,y = tree->ob_y - 3;
  157.     reg int w = tree->ob_width + 5,h = tree->ob_height + 5;
  158.  
  159.     graf_mouse(M_OFF,NULL);
  160.  
  161.     if (flag)
  162.     {
  163.         *ptr++ = x;
  164.         *ptr++ = y;
  165.         *ptr++ = x + w;
  166.         *ptr++ = y + h;
  167.         *ptr++ = 0;
  168.         *ptr++ = 0;
  169.         *ptr++ = w;
  170.         *ptr   = h;
  171.         vro_cpyfm(x_handle,3,pxy,screen,form);
  172.     }
  173.     else
  174.     {
  175.         *ptr++ = 0;
  176.         *ptr++ = 0;
  177.         *ptr++ = w;
  178.         *ptr++ = h;
  179.         *ptr++ = x;
  180.         *ptr++ = y;
  181.         *ptr++ = x + w;
  182.         *ptr   = y + h;
  183.         vro_cpyfm(x_handle,3,pxy,form,screen);
  184.     }
  185.  
  186.     graf_mouse(M_ON,NULL);
  187. }
  188.  
  189. void _line(int x1,int y1,int x2,int y2)
  190. {
  191.     reg int pxy[4];
  192.  
  193.     pxy[0] = x1;
  194.     pxy[1] = y1;
  195.     pxy[2] = x2;
  196.     pxy[3] = y2;
  197.     v_pline(x_handle,2,pxy);
  198. }
  199.  
  200. void _bar(int x,int y,int w,int h,int interior,int color)
  201. {
  202.     reg int pxy[4];
  203.  
  204.     v_set_fill(color,interior,-1);
  205.  
  206.     pxy[0] = x;
  207.     pxy[1] = y;
  208.     pxy[2] = x + w;
  209.     pxy[3] = y + h;
  210.     v_bar(x_handle,pxy);
  211. }
  212.  
  213. void _rectangle(int sx,int sy,int dx,int dy)
  214. {
  215.     reg int pxy[10];
  216.  
  217.     pxy[0] = pxy[6] = pxy[8] = sx;
  218.     pxy[1] = pxy[3] = pxy[9] = sy;
  219.     pxy[2] = pxy[4] = dx;
  220.     pxy[5] = pxy[7] = dy;
  221.     v_pline(x_handle,5,pxy);
  222. }
  223.  
  224. void _beg_ctrl()
  225. {
  226.     wind_update(BEG_UPDATE);
  227.     wind_update(BEG_MCTRL);
  228. }
  229.  
  230. void _end_ctrl()
  231. {
  232.     wind_update(END_MCTRL);
  233.     wind_update(END_UPDATE);
  234. }
  235.  
  236. int _mouse_but(void)
  237. {
  238.     int but,dummy;
  239.  
  240.     if (_back_win && !_bevent)
  241.         vq_mouse(x_handle,&but,&dummy,&dummy);
  242.     else
  243.         graf_mkstate(&dummy,&dummy,&but,&dummy);
  244.  
  245.     return(but);
  246. }
  247.  
  248. void _mouse_pos(reg int *x,reg int *y)
  249. {
  250.     int dummy;
  251.     graf_mkstate(x,y,&dummy,&dummy);
  252. }
  253.  
  254. void _no_click()
  255. {
  256.     if (_mouse_but())
  257.     {
  258.         XEVENT event;
  259.  
  260.         event.ev_mflags = MU_BUTTON;
  261.         event.ev_mbmask = 3;
  262.         event.ev_mbclicks = 1;
  263.         event.ev_mbstate = 0;
  264.         Event_Multi(&event);
  265.     }
  266. }
  267.  
  268. /*************************/
  269.  
  270. int min(int v_1,int v_2)
  271. {
  272.     if (v_1<v_2)
  273.         return(v_1);
  274.     else
  275.         return(v_2);
  276. }
  277.  
  278. int max(int v_1,int v_2)
  279. {
  280.     if (v_1>v_2)
  281.         return(v_1);
  282.     else
  283.         return(v_2);
  284. }
  285.  
  286. void Min(int *var,int val)
  287. {
  288.     if (*var>val)
  289.         *var = val;
  290. }
  291.  
  292. void Max(int *var,int val)
  293. {
  294.     if (*var<val)
  295.         *var = val;
  296. }
  297.  
  298. int scan_2_ascii(int scan,int state)
  299. {
  300.     reg long old_stack;
  301.     reg KEYTAB *keytab = Keytbl((void *) -1l,(void *) -1l,(void *) -1l);
  302.  
  303.     if (state)
  304.     {
  305.         scan = (int) (((unsigned) scan)>>8);
  306.         if ((scan>=120) && (scan<=131))
  307.             scan -= 118;
  308.  
  309.         if (mint)
  310.             old_stack = (long) Super(NULL);
  311.  
  312.         if (state & 3)
  313.             scan = (int) *(keytab->shift+scan);
  314.         else
  315.             scan = (int) *(keytab->unshift+scan);
  316.  
  317.         if (mint)
  318.             Super((void *) old_stack);
  319.     }
  320.  
  321.     scan &= 0xff;
  322.     if (scan>='a')
  323.     {
  324.         if (scan<='z')
  325.             scan -= 32;
  326.         else if (scan=='ä')
  327.             scan='Ä';
  328.         else if (scan=='ö')
  329.             scan='Ö';
  330.         else if (scan=='ü')
  331.             scan='Ü';
  332.     }
  333.     return(scan);
  334. }
  335.  
  336. void mfdb(MFDB *fm,int *adr,int w,int h,int st,int pl)
  337. {
  338.     fm->fd_addr        = adr;
  339.     fm->fd_w        = (w+15) & 0xfff0;
  340.     fm->fd_h        = h;
  341.     fm->fd_wdwidth    = fm->fd_w>>4;
  342.     fm->fd_stand    = st;
  343.     fm->fd_nplanes    = pl;
  344. }
  345.  
  346. long mfdb_size(MFDB *fm)
  347. {
  348.     return ((long) (fm->fd_wdwidth<<1) * (long) fm->fd_h * (long) fm->fd_nplanes);
  349. }
  350.  
  351. int _call_event_handler(int msg,XEVENT *event,int sendkey)
  352. {
  353.     reg int used;
  354.  
  355.     if (event_handler!=NULL && (handler_events & msg))
  356.     {
  357.         reg int old = event->ev_mwich;
  358.  
  359.         event->ev_mwich = msg;
  360.         used = event_handler(event);
  361.         event->ev_mwich = old;
  362.     }
  363.     else
  364.         used = 0;
  365.  
  366.     if ((msg & MU_KEYBD) && sendkey && _dia_len==0 && (used & MU_KEYBD)==0)
  367.     {
  368.         if (AvServer>=0)
  369.         {
  370.             int msg[8];
  371.             msg[3] = event->ev_mmokstate;
  372.             msg[4] = event->ev_mkreturn;
  373.             AvSendMsg(AvServer,AV_SENDKEY,msg);
  374.         }
  375.         else if (!multi && find_id(0)!=NULL)
  376.             XAccSendKey(0, event->ev_mkreturn, event->ev_mmokstate);
  377.     }
  378.  
  379.     return (used);
  380. }
  381.  
  382. static void cycle_close_window(int cycle,int titel)
  383. {
  384.     reg WIN *window,*wins,*last;
  385.     int top,dummy,mbuf[8];
  386.  
  387.     if (_dia_len==0)
  388.     {
  389.         if (menu_available && titel>0 && menu!=NULL)
  390.             menu_tnormal(menu,titel,1);
  391.  
  392.         if (_opened>0)
  393.         {
  394.             if (cycle && _opened==1)
  395.                 return;
  396.  
  397.             wind_xget(0,WF_TOP,&top,&dummy,&dummy,&dummy);
  398.             if ((window=get_window(top))!=NULL)
  399.             {
  400.                 if (cycle)
  401.                 {
  402.                     wins = window+1;
  403.                     last = &_windows[MAX_WINDOWS];
  404.                     while (wins<last)
  405.                         if (wins->handle>0)
  406.                             break;
  407.                         else
  408.                             wins++;
  409.  
  410.                     if (wins>=last)
  411.                     {
  412.                         last = window;
  413.                         wins = _windows;
  414.                         while (wins<last)
  415.                             if (wins->handle>0)
  416.                                 break;
  417.                             else
  418.                                 wins++;
  419.                     }
  420.                 }
  421.                 else
  422.                     wins = window;
  423.  
  424.                 mbuf[3] = wins->handle;
  425.                 AvSendMsg(ap_id,(cycle) ? WIN_TOPPED : WIN_CLOSED,mbuf);
  426.             }
  427.         }
  428.     }
  429. }
  430.  
  431. void Event_Handler(int (*init)(XEVENT *,int),int (*handler)(XEVENT *))
  432. {
  433.     if (init!=NULL || handler==NULL)
  434.         event_init = init;
  435.  
  436.     if (handler!=NULL || init==NULL)
  437.         event_handler = handler;
  438.  
  439.     if (event_handler==NULL)
  440.         event_init = NULL;
  441. }
  442.  
  443. typedef struct
  444. {
  445.     long    type;
  446.     long    what;
  447. } APPLRECORD;
  448.  
  449. static APPLRECORD record[] = {{1l,0x10000l}, {0l,10l}, {1l,0x100001l}};
  450.  
  451. void Event_Timer(int locount,int hicount)
  452. {
  453.     XEVENT event;
  454.  
  455.     event.ev_mflags = MU_TIMER|MU_MESAG;
  456.     event.ev_mtlocount = locount;
  457.     event.ev_mthicount = hicount;
  458.     event.ev_mtlast = 0;
  459.  
  460.     while (Event_Multi(&event) & MU_MESAG);
  461. }
  462.  
  463. static int icfs_iconify(WIN *window,int iconify,int old_top)
  464. {
  465.     if (iconify)
  466.     {
  467.         int x,y,w,h,top,dummy;
  468.  
  469.         if (old_top==FALSE)
  470.             wind_xget(0,WF_TOP,&top,&dummy,&dummy,&dummy);
  471.         else
  472.             top = old_top;
  473.  
  474.         if (top==window->handle)
  475.             top = FALSE;
  476.  
  477.         if (window->iconified & (ICONIFIED|ICFS))
  478.             return (TRUE);
  479.         else if (!(window->gadgets & SMALLER))
  480.             return (FAIL);
  481.         else if ((window->posnr=(*_icfs)(ICF_GETPOS,&x,&y,&w,&h))>0)
  482.         {
  483.             wind_xget(window->handle,WF_CURRXYWH,&window->x,&window->y,&window->w,&window->h);
  484.             wind_close(window->handle);
  485.             wind_delete(window->handle);
  486.             window->handle = wind_create(NAME|MOVER,desk.g_x,desk.g_y,desk.g_w,desk.g_h);
  487.             wind_open(window->handle,x,y,w,h);
  488.             window->iconified |= ICFS;
  489.  
  490.             if (top>=0)
  491.                 wind_set((top>0) ? top : window->handle,WF_TOP);
  492.  
  493.             return (TRUE);
  494.         }
  495.         else
  496.             return (FALSE);
  497.     }
  498.     else
  499.     {
  500.         if (window->iconified & ICFS)
  501.         {
  502.             wind_close(window->handle);
  503.             wind_delete(window->handle);
  504.             window->handle = wind_create(window->gadgets,desk.g_x,desk.g_y,desk.g_w,desk.g_h);
  505.             wind_set(window->handle,WF_BEVENT,_back_win);
  506.             wind_open(window->handle,window->x,window->y,window->w,window->h);
  507.             (*_icfs)(ICF_FREEPOS,window->posnr);
  508.             window->iconified &= ~ICFS;
  509.         }
  510.         return (TRUE);
  511.     }
  512. }
  513.  
  514. static int handle_messag(XEVENT *event,int no_messag)
  515. {
  516.     GRECT win;
  517.     reg WIN *window;
  518.     reg int events,flags,i,state;
  519.     reg int *msg = event->ev_mmgpbuf;
  520.  
  521.     if (_XAccComm(msg)==FALSE)
  522.     {
  523.         events = event->ev_mwich;
  524.         flags = event->ev_mflags;
  525.  
  526.         switch (msg[0])
  527.         {
  528.         case MN_SELECTED:
  529.             if (_cycle>0 && msg[4]==_cycle)
  530.             {
  531.                 cycle_close_window(TRUE,msg[3]);
  532.                 events &= ~MU_MESAG;
  533.             }
  534.             else if (_close>0 && msg[4]==_close)
  535.             {
  536.                 cycle_close_window(FALSE,msg[3]);
  537.                 events &= ~MU_MESAG;
  538.             }
  539.             break;
  540.         case WM_SHADED:
  541.             if ((window=get_window(msg[3]))!=NULL)
  542.             {
  543.                 window->iconified |= SHADE;
  544.                 goto _win_changed;
  545.             }
  546.             break;
  547.         case WM_UNSHADED:
  548.             if ((window=get_window(msg[3]))!=NULL)
  549.             {
  550.                 window->iconified &= ~SHADE;
  551.                 goto _win_changed;
  552.             }
  553.             break;
  554.         case WM_ICONIFY:
  555.             if ((window=get_window(msg[3]))!=NULL)
  556.             {
  557.                 if (!(window->iconified & (ICONIFIED|ICFS)))
  558.                 {
  559.                     wind_set(msg[3],WF_ICONIFY,msg[4],msg[5],msg[6],msg[7]);
  560.                     window->iconified |= ICONIFIED;
  561.                     goto _win_changed;
  562.                 }
  563.             }
  564.             break;
  565.         case WM_UNICONIFY:
  566.             if ((window=get_window(msg[3]))!=NULL)
  567.             {
  568.                 if ((window->iconified & (ICONIFIED|ICFS)))
  569.                 {
  570.                     wind_set(msg[3],WF_UNICONIFY,msg[4],msg[5],msg[6],msg[7]);
  571.                     window->iconified &= ~(ICONIFIED|ICFS);
  572.                     goto _win_changed;
  573.                 }
  574.             }
  575.             break;
  576.         case WM_CLOSED:
  577.             state = (event->ev_mmokstate & (K_RSHIFT|K_LSHIFT|K_ALT));
  578.             if (_icfs!=NULL && state && (window=get_window(msg[3]))!=NULL)
  579.             {
  580.                 int top,dummy;
  581.  
  582.                 if (state & K_ALT)
  583.                     i = 1;
  584.                 else
  585.                 {
  586.                     i = MAX_WINDOWS;
  587.                     window = _windows;
  588.                 }
  589.  
  590.                 wind_xget(0,WF_TOP,&top,&dummy,&dummy,&dummy);
  591.  
  592.                 for (;--i>=0;)
  593.                 {
  594.                     if (window->handle>0)
  595.                     {
  596.                         if (top==window->handle)
  597.                         {
  598.                              if (icfs_iconify(window,TRUE,FAIL)==FALSE)
  599.                                 break;
  600.                             top = window->handle;
  601.                         }
  602.                         else if (icfs_iconify(window,TRUE,FAIL)==FALSE)
  603.                             break;
  604.                     }
  605.  
  606.                     if (state & (K_RSHIFT|K_LSHIFT))
  607.                         window++;
  608.                 }
  609.  
  610.                 wind_set(top,WF_TOP);
  611.  
  612.                 if (state & K_ALT)
  613.                 {
  614.                     _win_changed:
  615.                     *(WIN **) &msg[4] = window;
  616.                 }
  617.                 else
  618.                     *(WIN **) &msg[4] = NULL;
  619.                 msg[0] = WIN_CHANGED;
  620.             }
  621.             break;
  622.         case WM_MOVED:
  623.             if ((window=get_window(msg[3]))!=NULL && (window->iconified & (ICONIFIED|ICFS)))
  624.             {
  625.                 Max(&msg[4],desk.g_x);
  626.                 Max(&msg[5],desk.g_y);
  627.                 wind_set(window->handle,WF_CURRXYWH,msg[4],msg[5],msg[6],msg[7]);
  628.                 events &= ~MU_MESAG;
  629.             }
  630.             break;
  631.         case WM_TOPPED:
  632.             wind_xget(msg[3],WF_WORKXYWH,&win.g_x,&win.g_y,&win.g_w,&win.g_h);
  633.             if (rc_inside(event->ev_mmox,event->ev_mmoy,&win))
  634.             {
  635.                 if (_icfs!=NULL && (window=get_window(msg[3]))!=NULL && (window->iconified & ICFS))
  636.                 {
  637.                     icfs_iconify(window,FALSE,FALSE);
  638.                     msg[0] = WIN_CHANGED;
  639.                     *(WIN **) &msg[4] = window;
  640.                 }
  641.                 else if (!_bevent && _back_win && (flags & (MU_BUTTON1|MU_BUTTON2)))
  642.                 {
  643.                     events &= ~MU_MESAG;
  644.                     event->ev_mmobutton = 1;
  645.                     event->ev_mb1return = event->ev_mb2return = 1;
  646.  
  647.                     if (event->ev_mb1clicks>=256 || (event->ev_mb1state & 1))
  648.                         events |= MU_BUTTON1;
  649.  
  650.                     if (event->ev_mb2clicks>=256 || (event->ev_mb2state & 1))
  651.                         events |= MU_BUTTON2;
  652.  
  653.                     if (_mouse_but() & 1)
  654.                         appl_tplay(record,3,100);
  655.                 }
  656.             }
  657.             break;
  658.         case WIN_CLOSED:
  659.             msg[0] = WM_CLOSED;
  660.             break;
  661.         case WIN_TOPPED:
  662.             msg[0] = WM_TOPPED;
  663.             break;
  664.         case AV_SENDKEY:
  665.             events &= ~MU_MESAG;
  666.             if (flags & MU_KEYBD)
  667.             {
  668.                 events |= MU_KEYBD;
  669.                 event->ev_mkreturn = msg[4];
  670.                 event->ev_mmokstate = msg[3];
  671.             }
  672.             break;
  673.         case ACC_KEY:
  674.             events &= ~MU_MESAG;
  675.             if (flags & MU_KEYBD)
  676.             {
  677.                 events |= MU_KEYBD;
  678.                 event->ev_mkreturn = msg[3];
  679.                 event->ev_mmokstate = msg[4];
  680.                 XAccSendAck(msg[1],1);
  681.             }
  682.             else
  683.                 XAccSendAck(msg[1],0);
  684.             break;
  685.         case ACC_META:
  686.             if (_xacc_msgs & X_MSG_META)
  687.                 break;
  688.         case ACC_IMG:
  689.             if (_xacc_msgs & X_MSG_IMG)
  690.                 break;
  691.         case ACC_TEXT:
  692.             if (_xacc_msgs & X_MSG_TEXT)
  693.                 break;
  694.             XAccSendAck(msg[1],0);
  695.             events &= ~MU_MESAG;
  696.             break;
  697.         }
  698.  
  699.         if (no_messag==0 && (events & MU_MESAG))
  700.         {
  701.             event->ev_mwich = events;
  702.             _messag_handler(FALSE,event,NULL,NULL);
  703.             return (event->ev_mwich);
  704.         }
  705.         else
  706.             return (events);
  707.     }
  708.     else
  709.         return (event->ev_mwich & (~MU_MESAG));
  710. }
  711.  
  712. typedef struct
  713. {
  714.     unsigned int ev_mtlocount,ev_mthicount;
  715. } E_TIMER;
  716.  
  717. typedef struct
  718. {
  719.     int ev_mmflags,ev_mmx,ev_mmy,ev_mmwidth,ev_mmheight;
  720. } E_MOUSE;
  721.  
  722. typedef struct
  723. {
  724.     int ev_mbclicks,ev_mbmask,ev_mbstate;
  725. } E_BUTTON;
  726.  
  727. static E_BUTTON click = {258,3,0}, no_click = {2,3,0};
  728.  
  729. static int Wait_for_Event(XEVENT *event)
  730. {
  731.     E_MOUSE mu_m1;
  732.     E_BUTTON mu_button1;
  733.     E_TIMER mu_timer1;
  734.  
  735.     reg int events = 0, flags = event->ev_mflags, t_flags = (flags & (MU_TIMER1|MU_TIMER2));
  736.     reg int in, button = 0;
  737.  
  738.     int nx,ny,in1,in3,in4;
  739.     long timer,timer1,timer2,time;
  740.  
  741.     event->ev_mflags &= MU_MESAG|MU_BUTTON|MU_KEYBD|MU_M1|MU_M2|MU_TIMER;
  742.  
  743.     if (flags & (MU_M3|MU_M4))
  744.     {
  745.         mu_m1 = *(E_MOUSE *) &event->ev_mm1flags;
  746.  
  747.         _mouse_pos(&nx,&ny);
  748.         in1 = rc_inside(nx,ny,(GRECT *) &event->ev_mm1x);
  749.         in3 = rc_inside(nx,ny,(GRECT *) &event->ev_mm3x);
  750.         in4 = rc_inside(nx,ny,(GRECT *) &event->ev_mm4x);
  751.  
  752.         event->ev_mm1flags = event->ev_mm1width = event->ev_mm1height = 1;
  753.         event->ev_mm1x = nx;
  754.         event->ev_mm1y = ny;
  755.  
  756.         event->ev_mflags |= MU_M1;
  757.     }
  758.  
  759.     if (flags & MU_BUTTON2)
  760.     {
  761.         mu_button1 = *(E_BUTTON *) &event->ev_mb1clicks;
  762.  
  763.         if (event->ev_mflags & MU_BUTTON1)
  764.         {
  765.             if (event->ev_mb1clicks<256 && event->ev_mb1state==0)
  766.             {
  767.                 if (event->ev_mb2clicks<256 && event->ev_mb2state==0)
  768.                     *(E_BUTTON *) &event->ev_mb1clicks = no_click;
  769.                 else
  770.                 {
  771.                     *(E_BUTTON *) &event->ev_mb1clicks = click;
  772.                     button = -1;
  773.                 }
  774.             }
  775.             else
  776.             {
  777.                 if (event->ev_mb2clicks<256 && event->ev_mb2state==0)
  778.                     button = -1;
  779.                 *(E_BUTTON *) &event->ev_mb1clicks = click;
  780.             }
  781.         }
  782.         else
  783.         {
  784.             *(E_BUTTON *) &event->ev_mb1clicks = *(E_BUTTON *) &event->ev_mb2clicks;
  785.             event->ev_mflags |= MU_BUTTON1;
  786.             button = 1;
  787.         }
  788.     }
  789.  
  790.     if (t_flags || button<0)
  791.     {
  792.         mu_timer1 = *(E_TIMER *) &event->ev_mt1locount;
  793.  
  794.         event->ev_mflags |= MU_TIMER;
  795.     }
  796.  
  797.     do
  798.     {
  799.         if (t_flags)
  800.         {
  801.             time = clock()*5;
  802.  
  803.             if (t_flags & MU_TIMER1)
  804.             {
  805.                 timer1 = (((long) event->ev_mt1hicount)<<16)|event->ev_mt1locount;
  806.                 if (event->ev_mt1last<=0)
  807.                     event->ev_mt1last = time;
  808.                 else
  809.                     timer1 += event->ev_mt1last - time;
  810.             }
  811.  
  812.             if (t_flags & MU_TIMER2)
  813.             {
  814.                 timer2 = (((long) event->ev_mt2hicount)<<16)|event->ev_mt2locount;
  815.                 if (event->ev_mt2last<=0)
  816.                     event->ev_mt2last = time;
  817.                 else
  818.                     timer2 += event->ev_mt2last - time;
  819.             }
  820.  
  821.             switch (t_flags)
  822.             {
  823.             case MU_TIMER1:
  824.                 timer = timer1;
  825.                 break;
  826.             case MU_TIMER2:
  827.                 timer = timer2;
  828.                 break;
  829.             default:
  830.                 timer = (timer1<timer2) ? timer1 : timer2;
  831.             }
  832.  
  833.             if (timer<2 || button<0)
  834.             {
  835.                 event->ev_mthicount = 0;
  836.                 event->ev_mtlocount = 1;
  837.                 events = MU_TIMER;
  838.             }
  839.             else
  840.             {
  841.                 event->ev_mtlocount = (int) timer;
  842.                 event->ev_mthicount = (int) (timer>>16);
  843.             }
  844.  
  845.             if (timer>0)
  846.                 time += timer;
  847.         }
  848.         else if (button<0)
  849.         {
  850.             event->ev_mthicount = 0;
  851.             event->ev_mtlocount = 1;
  852.         }
  853.  
  854.         events |= EvntMulti((EVENT *) event);
  855.  
  856.         if (!_bevent && _back_win)
  857.         {
  858.             event->ev_mmobutton = _mouse_but();
  859.  
  860.             if (events & MU_BUTTON1)
  861.             {
  862.                 in = event->ev_mmobutton & event->ev_mb1mask;
  863.  
  864.                 if (event->ev_mb1clicks<256)
  865.                 {
  866.                     if (in!=event->ev_mb1state)
  867.                         events &= ~MU_BUTTON1;
  868.                 }
  869.                 else if (in==0)
  870.                     events &= ~MU_BUTTON1;
  871.             }
  872.         }
  873.  
  874.         if (flags & MU_BUTTON2)
  875.         {
  876.             event->ev_mb2return = event->ev_mb1return;
  877.  
  878.             if (button>0)
  879.             {
  880.                 if (events & MU_BUTTON1)
  881.                 {
  882.                     events &= ~MU_BUTTON1;
  883.                     events |= MU_BUTTON2;
  884.                 }
  885.             }
  886.             else if (button<0 || (events & MU_BUTTON1))
  887.             {
  888.                 if (events & MU_BUTTON1)
  889.                     events &= ~MU_BUTTON1;
  890.                 else
  891.                     event->ev_mb2return = event->ev_mb1return = 1;
  892.  
  893.                 in = event->ev_mmobutton & event->ev_mb2mask;
  894.                 if (event->ev_mb2clicks<256)
  895.                 {
  896.                     if (in==event->ev_mb2state)
  897.                     {
  898.                         events |= MU_BUTTON2;
  899.                         if (in==0 && button<0)
  900.                             event->ev_mb2return = 1;
  901.                     }
  902.                 }
  903.                 else if (in)
  904.                     events |= MU_BUTTON2;
  905.  
  906.                 in = event->ev_mmobutton & mu_button1.ev_mbmask;
  907.                 if (mu_button1.ev_mbclicks<256)
  908.                 {
  909.                     if (in==mu_button1.ev_mbstate)
  910.                     {
  911.                         events |= MU_BUTTON1;
  912.                         if (in==0 && button<0)
  913.                             event->ev_mb1return = 1;
  914.                     }
  915.                 }
  916.                 else if (in)
  917.                     events |= MU_BUTTON1;
  918.             }
  919.         }
  920.  
  921.         if ((events & MU_M1) && (flags & (MU_M3|MU_M4)))
  922.         {
  923.             events &= ~MU_M1;
  924.  
  925.             ny = event->ev_mmox;
  926.             nx = event->ev_mmoy;
  927.  
  928.             if (flags & MU_M1)
  929.             {
  930.                 in = rc_inside(nx,ny,(GRECT *) &mu_m1.ev_mmx) - in1;
  931.                 if ((in<0 && mu_m1.ev_mmflags) || (in>0 && mu_m1.ev_mmflags==0))
  932.                     events |= MU_M1;
  933.             }
  934.  
  935.             if (flags & MU_M3)
  936.             {
  937.                 in = rc_inside(nx,ny,(GRECT *) event->ev_mm3x) - in3;
  938.                 if ((in<0 && event->ev_mm3flags) || (in>0 && event->ev_mm3flags==0))
  939.                     events |= MU_M3;
  940.             }
  941.  
  942.             if (flags & MU_M4)
  943.             {
  944.                 in = rc_inside(nx,ny,(GRECT *) event->ev_mm4x) - in4;
  945.                 if ((in<0 && event->ev_mm4flags) || (in>0 && event->ev_mm4flags==0))
  946.                     events |= MU_M4;
  947.             }
  948.         }
  949.  
  950.         if (events & MU_TIMER)
  951.         {
  952.             if (t_flags && (timer<2 || button>=0))
  953.             {
  954.                 switch (t_flags)
  955.                 {
  956.                 case MU_TIMER1:
  957.                     event->ev_mt1last = time;
  958.                     break;
  959.                 case MU_TIMER2:
  960.                     events &= ~MU_TIMER1;
  961.                     events |= MU_TIMER2;
  962.                     event->ev_mt2last = time;
  963.                     break;
  964.                 default:
  965.                     if (timer1<timer2)
  966.                         event->ev_mt1last = time;
  967.                     else
  968.                     {
  969.                         events &= ~MU_TIMER1;
  970.                         events |= MU_TIMER2;
  971.                         event->ev_mt2last = time;
  972.                     }
  973.                 }
  974.             }
  975.             else
  976.                 events &= ~MU_TIMER;
  977.         }
  978.     } while (events==0);
  979.  
  980.     if (flags & (MU_M3|MU_M4))
  981.         *(E_MOUSE *) &event->ev_mm1flags = mu_m1;
  982.  
  983.     if (t_flags || button<0)
  984.         *(E_TIMER *) &event->ev_mt1locount = mu_timer1;
  985.  
  986.     if (flags & MU_BUTTON2)
  987.         *(E_BUTTON *) &event->ev_mb1clicks = mu_button1;
  988.  
  989.     event->ev_mwich = events;
  990.     event->ev_mflags = flags;
  991.  
  992.     return (events);
  993. }
  994.  
  995. int Event_Multi(XEVENT *event)
  996. {
  997.     E_BUTTON mu_button1;
  998.     reg WIN *window;
  999.     XEVENT local_event;
  1000.     reg int events,no_messag,wait_events,key,flags;
  1001.     int available,old_flags,button,msg[8];
  1002.  
  1003.     if (event==NULL)
  1004.     {
  1005.         event = &local_event;
  1006.         old_flags = no_messag = wait_events = event->ev_mflags = 0;
  1007.     }
  1008.     else
  1009.     {
  1010.         old_flags = event->ev_mflags;
  1011.         no_messag = (old_flags & MU_NO_HANDLER);
  1012.         wait_events = (old_flags ^ no_messag);
  1013.     }
  1014.  
  1015.     if (_popup)
  1016.         available = MU_TIMER1|MU_TIMER2;
  1017.     else
  1018.         available = MU_MESAG|MU_KEYBD|MU_BUTTON1|MU_BUTTON2|MU_M1|MU_M2|MU_M3|MU_M4|MU_TIMER1|MU_TIMER2;
  1019.     available &= ~(wait_events & (MU_BUTTON1|MU_BUTTON2|MU_M1|MU_M2|MU_M3|MU_M4|MU_TIMER1|MU_TIMER2));
  1020.  
  1021.     do
  1022.     {
  1023.         flags = wait_events;
  1024.         if (event_init!=NULL)
  1025.             flags |= (handler_events = event_init(event,available) & available);
  1026.         else if (event_handler!=NULL && !_popup)
  1027.             handler_events = available;
  1028.         else
  1029.             handler_events = 0;
  1030.  
  1031.         if (_icfs!=NULL && _opened>0)
  1032.         {
  1033.             if (!(flags & (MU_BUTTON1|MU_BUTTON2)) && (available & MU_BUTTON1))
  1034.             {
  1035.                 flags |= MU_BUTTON1;
  1036.  
  1037.                 mu_button1 = *(E_BUTTON *) &event->ev_mb1clicks;
  1038.                 *(E_BUTTON *) &event->ev_mb1clicks = click;
  1039.                 button = TRUE;
  1040.             }
  1041.             else
  1042.                 button = FALSE;
  1043.  
  1044.             if (!(flags & MU_KEYBD) && (available & MU_KEYBD))
  1045.                 flags |= MU_KEYBD;
  1046.         }
  1047.         else
  1048.             button = FALSE;
  1049.  
  1050.         event->ev_mflags = flags;
  1051.         events = Wait_for_Event(event);
  1052.         event->ev_mflags = old_flags;
  1053.  
  1054.         if (button)
  1055.             *(E_BUTTON *) &event->ev_mb1clicks = mu_button1;
  1056.  
  1057.         if (_icfs!=NULL && _opened>0 && (event->ev_mmobutton & 1))
  1058.         {
  1059.             if ((window=get_window(wind_find(event->ev_mmox,event->ev_mmoy)))!=NULL && (window->iconified & ICFS))
  1060.             {
  1061.                 icfs_iconify(window,FALSE,FALSE);
  1062.                 *(WIN **) &msg[4] = window;
  1063.                 AvSendMsg(ap_id,WIN_CHANGED,msg);
  1064.                 events &= ~(MU_BUTTON1|MU_BUTTON2);
  1065.             }
  1066.         }
  1067.  
  1068.         if (events & MU_MESAG)
  1069.             events = handle_messag(event,no_messag);
  1070.  
  1071.         if ((events & MU_KEYBD) && _dia_len==0 && (event->ev_mmokstate & K_CTRL))
  1072.         {
  1073.             if ((event->ev_mkreturn>>8)==0x66)
  1074.             {
  1075.                 if (_opened>0 && _icfs!=NULL)
  1076.                 {
  1077.                     int top,dummy;
  1078.  
  1079.                     wind_xget(0,WF_TOP,&top,&dummy,&dummy,&dummy);
  1080.                     if ((window=get_window(top))!=NULL && !(window->iconified & ICONIFIED))
  1081.                     {
  1082.                         icfs_iconify(window,!(window->iconified & ICFS),top);
  1083.                         *(WIN **) &msg[4] = window;
  1084.                         AvSendMsg(ap_id,WIN_CHANGED,msg);
  1085.                         events &= ~MU_KEYBD;
  1086.                     }
  1087.                 }
  1088.             }
  1089.             else if ((key=scan_2_ascii(event->ev_mkreturn,event->ev_mmokstate))!='\0')
  1090.             {
  1091.                 key = _upper(key);
  1092.                 if (key==_cycle_hot || key==_close_hot)
  1093.                 {
  1094.                     cycle_close_window(key==_cycle_hot,0);
  1095.                     events &= ~MU_KEYBD;
  1096.                 }
  1097.             }
  1098.         }
  1099.  
  1100.         if (no_messag==0)
  1101.         {
  1102.             if (handler_events & events)
  1103.                 events &= ~(_call_event_handler(events,event,(wait_events & MU_KEYBD) ? FALSE : FAIL) & (~wait_events));
  1104.             events &= wait_events;
  1105.         }
  1106.     } while (!events);
  1107.  
  1108.     return (event->ev_mwich = events);
  1109. }
  1110.  
  1111. void rc_sc_clear(GRECT *dest)
  1112. {
  1113.     rc_sc_copy(dest,dest->g_x,dest->g_y,0);
  1114. }
  1115.  
  1116. void rc_sc_invert(GRECT *dest)
  1117. {
  1118.     rc_sc_copy(dest,dest->g_x,dest->g_y,D_INVERT);
  1119. }
  1120.  
  1121. void rc_sc_copy(GRECT *source,int dx,int dy,int mode)
  1122. {
  1123.     reg GRECT work = *source;
  1124.  
  1125.     if (rc_intersect(&desk,&work))
  1126.     {
  1127.         reg GRECT dest;
  1128.  
  1129.         dest.g_x = dx;
  1130.         dest.g_y = dy;
  1131.         dest.g_w = work.g_w;
  1132.         dest.g_h = work.g_h;
  1133.  
  1134.         if (rc_intersect(&desk,&dest))
  1135.         {
  1136.             reg int pxy[8];
  1137.  
  1138.             rc_grect_to_array(&work,pxy);
  1139.             rc_grect_to_array(&dest,pxy+4);
  1140.             vro_cpyfm(x_handle,mode,pxy,screen,screen);
  1141.         }
  1142.     }
  1143. }
  1144.  
  1145. void save_clipping(int *area)
  1146. {
  1147.     reg long *clip=(long *) clipping_area;
  1148.  
  1149.     *((long *) area)++ = *clip++;
  1150.     *((long *) area)++ = *clip++;
  1151. }
  1152.  
  1153. void restore_clipping(int *area)
  1154. {
  1155.     reg long *clip=(long *) clipping_area;
  1156.  
  1157.     vs_clip(x_handle,1,area);
  1158.     *clip++ = *((long *) area)++;
  1159.     *clip++ = *((long *) area)++;
  1160. }
  1161.